/**
 * 
 */
package javavis.jip2d.functions;

import javavis.base.ImageType;
import javavis.base.JIPException;
import javavis.base.parameter.JIPParamInt;
import javavis.jip2d.base.FunctionGroup;
import javavis.jip2d.base.JIPFunction;
import javavis.jip2d.base.JIPImage;
import javavis.jip2d.base.bitmaps.JIPImgBitmap;
import javavis.jip2d.base.geometrics.JIPImgGeometric;

/**
 * @author miguel
 *
 */
public class FEqualizeMean extends JIPFunction {
	private static final long serialVersionUID = 7432834000464545790L;

	public FEqualizeMean() {
		name = "FEqualizeMean";
		description = "Move the weighted mean of the histogram to a given level";
		groupFunc = FunctionGroup.Adjustment;
		
		JIPParamInt p1 = new JIPParamInt("level", false, true);
		p1.setDescription("Level to move the mean");
		p1.setDefault(128);
		
		addParam(p1);
	}

	public JIPImage processImg(JIPImage img) throws JIPException {
		ImageType t = img.getType();
		if(img instanceof JIPImgGeometric || t == ImageType.BIT) {
			throw new JIPException("Input image must be bitmap different from BIT.");
		}
		JIPImgBitmap bmp = (JIPImgBitmap)img;
		int level = getParamValueInt("level");
		double mean, rate;
		double []pixels;
		int max=0;
		int b = bmp.getNumBands();
		int w = bmp.getWidth();
		int h = bmp.getHeight();
		int totalPix = w*h;
		JIPImgBitmap res = (JIPImgBitmap)JIPImgBitmap.newImage(b, w, h, t);
		switch (t) {
			case BYTE: 
			case COLOR: 
			case FLOAT:max=256; break;
			case SHORT: max=65536; break;
		}
		for (int bi=0; bi<b; bi++) {
			pixels = bmp.getAllPixels(bi);
			// First, calculate the histogram
			int histo[] = new int[max];
			for (int k=0; k < totalPix; k++) 
				histo[(int)(pixels[k]*(t==ImageType.FLOAT?255:1))]++;
			// Then, calculate weighted mean
			mean=0.0;
			for (int i=0; i<max; i++) {
				mean += i*histo[i];
			}
			mean /= totalPix;
			rate = level / mean;
			for (int k=0; k < totalPix; k++) 
				pixels[k] *= rate;
			res.setAllPixels(bi,pixels);
		}
		return res;
	}

}